package com.gin.kotlin.no_gay_alliance.fragment.topiclist

import android.content.DialogInterface
import android.os.Bundle
import android.util.Log
import android.view.View
import com.gin.kotlin.no_gay_alliance.R
import com.gin.kotlin.no_gay_alliance.activity.TopicListActivity
import com.gin.kotlin.no_gay_alliance.adapter.TopicListAdapter
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.argument.TopicListArgument
import com.gin.kotlin.no_gay_alliance.argument.TopicListArgument.Type
import com.gin.kotlin.no_gay_alliance.base.AbstractBindingActivity
import com.gin.kotlin.no_gay_alliance.base.AbstractBindingFragment
import com.gin.kotlin.no_gay_alliance.base.AlertDialogUtils
import com.gin.kotlin.no_gay_alliance.callback.RCallback
import com.gin.kotlin.no_gay_alliance.databinding.FragmentTopicPageBinding
import com.gin.kotlin.no_gay_alliance.enums.HandlerMessageWhat
import com.gin.kotlin.no_gay_alliance.provider.ngaphp.TopicListProvider
import com.gin.nga.callback.NgaCallback
import com.gin.nga.response.base.NgaResponse
import com.gin.nga.response.topic.TopicInfo
import com.gin.nga.response.topic.TopicListBody
import retrofit2.Call
import retrofit2.Response

/**
 * 一页主题
 */
class TopicPageFragment : AbstractBindingFragment<FragmentTopicPageBinding>(), RCallback<TopicListBody, TopicListArgument> {
    private var blockedTopics: List<TopicInfo>? = null
    private lateinit var argument: TopicListArgument
    private lateinit var adapter: TopicListAdapter

    /**
     * 删除选中的收藏主题
     */
    fun favorDelete() {
        val topic = adapter.selected.map { it.getFavorId() }
        if (topic.isEmpty()) {
            handler?.toast(getString(R.string.toast_message_no_favor_selected))
            return
        }
        AlertDialogUtils.builder(
            requireContext(),
            getString(R.string.dialog_title_favor_delete),
            getString(R.string.dialog_message_favor_delete, topic.size.toString()),
            listener = { _, which ->
                if (which == DialogInterface.BUTTON_POSITIVE)
                // 移除收藏请求
                    App.INSTANCE.ngaApi.favorApi.del(argument.folderId!!, topic).enqueue(object : NgaCallback<List<String>> {
                        override fun onSuccess(
                            call: Call<NgaResponse<List<String>>>,
                            response: Response<NgaResponse<List<String>>>,
                            body: NgaResponse<List<String>>?,
                            data: List<String>?
                        ) {
                            data?.get(0)?.also { handler?.toast(it) }
                            adapter.selected.clear()
                            refresh()
                        }

                        override fun onError(
                            call: Call<NgaResponse<List<String>>>,
                            response: Response<NgaResponse<List<String>>>,
                            body: NgaResponse<List<String>>?,
                            errorMessage: String
                        ) {
                            handler?.toast(errorMessage)
                        }
                    })
            }).show()


    }

    override fun onCreateView() {
        val b = this.b ?: return

        this.adapter = TopicListAdapter(
            requireContext(),
            handler!!,
            hideForumName = this.argument.type == Type.COL_LIST || this.argument.type == Type.COL_SEARCH,
            checkable = this.argument.type == Type.FAVOR_FOLDER && (this.argument.authorUid == App.INSTANCE.account.userId || this.argument.authorUid == null)
        )
        b.recyclerView.adapter = adapter
        b.tvWarning.visibility = View.GONE
        b.swipeRefreshLayout.setOnRefreshListener { refresh() }

        // 发送请求
        request()
    }

    override fun handleArguments(bundle: Bundle) {
        this.argument = parseBundle(bundle, TopicListActivity.KEY_ARGUMENT, TopicListArgument::class.java)
    }

    override fun onResume() {
        super.onResume()
        // 发送消息更新当前页
        findParentHandler().sendMessage(HandlerMessageWhat.PAGE_UPDATED, this.argument.page!!)
        // 设置当前页
        (parentFragment as? AbstractTopicListFragment<*>)?.currentPageFragment = this

        syncBlockedTopics()
    }

    fun refresh() {
        Log.i(TAG, "刷新: ${mapper.writeValueAsString(this.argument)}")
        request(true)
    }

    private fun request(ignoreCache: Boolean = false) {
        val b = this.b ?: return

        b.tvWarning.visibility = View.GONE
        b.swipeRefreshLayout.isRefreshing = true

        TopicListProvider.getInstance().enqueue(this.argument, ignoreCache = ignoreCache, callback = this)
    }

    companion object {
        fun newInstance(argument: TopicListArgument) = TopicPageFragment().also { it.arguments = Bundle().also { b -> b.putParcelable(TopicListActivity.KEY_ARGUMENT, argument) } }
    }


    override fun onSuccess(data: TopicListBody, ignoreCache: Boolean) {
        val b = this.b ?: return

        //设置标题
        (requireActivity() as? AbstractBindingActivity<*>)?.also { a ->
            (data.currentForum?.colTitle ?: data.currentForum?.forumName)?.also { a.setToolbarTitle(it) }
        }
        Log.i(TAG, "请求成功: ${mapper.writeValueAsString(this.argument)}")
        ui {
            b.swipeRefreshLayout.isRefreshing = false
        }
        // 更新当前页信息
        data.getTotalPage()?.also {
            findParentHandler().sendMessage(HandlerMessageWhat.PAGE_UPDATED, this.argument.page!!, it)
        }
        // 更新当前版面信息
        data.currentForum?.also {
            findParentHandler().sendMessage(HandlerMessageWhat.CURRENT_FORUM_UPDATE, it)
        }

        // 用户回复模式下，按照当前页+5设置总页数
        if (this.argument.type == Type.USER_SEARCH) {
            findParentHandler().sendMessage(HandlerMessageWhat.PAGE_UPDATED, this.argument.page!!, this.argument.page!! + 5)
        }

        // 更新主题列表
        data.topics?.also { replies ->
            val banUsers = App.INSTANCE.database.banUserDao().list()
            val banKeywords = App.INSTANCE.database.banKeywordDao().list()
            val banTopics = App.INSTANCE.database.banTopicDao().list()

            fun isBlocked(topic: TopicInfo): Boolean {
                return App.INSTANCE.blockConfig?.isBlocked(topic) == true
                        || banUsers?.any { it.userId == topic.authorUid?.toLongOrNull() } == true
                        || banKeywords?.any { topic.title?.contains(it.value, true) == true } == true
                        || banTopics?.any { topic.getEntranceId() == it.topicId } == true
            }

            // 如果浏览模式为合集浏览或版面浏览，激活屏蔽机制
            val list = when (this.argument.type) {
                Type.COL_LIST, Type.FORUM_LIST -> {
                    this.blockedTopics = replies.filter { isBlocked(it) }
                    Log.w(TAG, "屏蔽主题: ${blockedTopics?.size} 个")
                    blockedTopics?.forEach { Log.d(TAG, "已屏蔽主题: ${it.title}") }
                    // 抛出被屏蔽的主题
                    syncBlockedTopics()

                    replies.filter { !isBlocked(it) }
                }

                else -> replies
            }
            this.adapter.replaceData(list)
        }
    }

    /**
     * 同步被屏蔽主题
     * @param blockedTopics List<TopicInfo>
     */
    private fun syncBlockedTopics() {
        handler?.sendMessage(HandlerMessageWhat.BLOCKED_TOPICS, blockedTopics)
    }

    override fun onError(errorMessage: String) {
        val b = this.b ?: return
        ui {
            b.tvWarning.visibility = View.VISIBLE
            b.swipeRefreshLayout.isRefreshing = false
            // 报错信息
            b.tvWarning.text = errorMessage
        }
        // 清空数据
        this.adapter.replaceData(listOf())
    }
}